<?php
defined('THINK_PATH') or exit();
// +----------------------------------------------------------------------------
// | PHP@妖孽 [三十年河东三十年河西,莫欺少年穷.!]
// +----------------------------------------------------------------------------
// | Copyright (c) 2014 http://www.itdaodan.com All rights reserved.
// +----------------------------------------------------------------------------
// | Author: PHP@妖孽 <dino_ma@163.com>
// +----------------------------------------------------------------------------
/**
 +------------------------------------------------------------------------------
 * PHP开发基础框架Admin函数库
 +------------------------------------------------------------------------------
 * @version   1.0
 * @since 2014-8-8
 +------------------------------------------------------------------------------
 */
/**
 * 记录行为日志，并执行该行为的规则
 * @param string $action 行为标识
 * @param string $model 触发行为的模型名
 * @param int $record_id 触发行为的记录id
 * @param int $user_id 执行行为的用户id
 * @return boolean
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function action_log($action = null, $model = null, $record_id = null, $user_id = null){

	//参数检查
	if(empty($action) || empty($model) || empty($record_id)){
		return '参数不能为空';
	}
	if(empty($user_id)){
		$user_id = is_login();
	}

	//查询行为,判断是否执行
	$action_info = M('Action')->getByName($action);
	if($action_info['status'] != 1){
		return '该行为被禁用或删除';
	}

	//插入行为日志
	$data['action_id']      =   $action_info['id'];
	$data['user_id']        =   $user_id;
	$data['action_ip']      =   ip2long(get_client_ip());
	$data['model']          =   $model;
	$data['record_id']      =   $record_id;
	$data['create_time']    =   NOW_TIME;
	//解析日志规则,生成日志备注
	if(!empty($action_info['log'])){
		if(preg_match_all('/\[(\S+?)\]/', $action_info['log'], $match)){
			$log['user']    =   $user_id;
			$log['record']  =   $record_id;
			$log['model']   =   $model;
			$log['time']    =   NOW_TIME;
			$log['data']    =   array('user'=>$user_id,'model'=>$model,'record'=>$record_id,'time'=>NOW_TIME);
			foreach ($match[1] as $value){
				$param = explode('|', $value);
				if(isset($param[1])){
					$replace[] = call_user_func($param[1],$log[$param[0]]);
				}else{
					$replace[] = $log[$param[0]];
				}
			}
			$data['remark'] =   str_replace($match[0], $replace, $action_info['log']);
		}else{
			$data['remark'] =   $action_info['log'];
		}
	}else{
		//未定义日志规则，记录操作url
		$data['remark']     =   '操作url：'.$_SERVER['REQUEST_URI'];
	}

	M('ActionLog')->add($data);

	if(!empty($action_info['rule'])){
		//解析行为
		$rules = parse_action($action, $user_id);

		//执行行为
		$res = execute_action($rules, $action_info['id'], $user_id);
	}
}

/**
 * 解析行为规则
 * 规则定义  table:$table|field:$field|condition:$condition|rule:$rule[|cycle:$cycle|max:$max][;......]
 * 规则字段解释：table->要操作的数据表，不需要加表前缀；
 *              field->要操作的字段；
 *              condition->操作的条件，目前支持字符串，默认变量{$self}为执行行为的用户
 *              rule->对字段进行的具体操作，目前支持四则混合运算，如：1+score*2/2-3
 *              cycle->执行周期，单位（小时），表示$cycle小时内最多执行$max次
 *              max->单个周期内的最大执行次数（$cycle和$max必须同时定义，否则无效）
 * 单个行为后可加 ； 连接其他规则
 * @param string $action 行为id或者name
 * @param int $self 替换规则里的变量为执行用户的id
 * @return boolean|array: false解析出错 ， 成功返回规则数组
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function parse_action($action = null, $self){
	if(empty($action)){
		return false;
	}

	//参数支持id或者name
	if(is_numeric($action)){
		$map = array('id'=>$action);
	}else{
		$map = array('name'=>$action);
	}

	//查询行为信息
	$info = M('Action')->where($map)->find();
	if(!$info || $info['status'] != 1){
		return false;
	}

	//解析规则:table:$table|field:$field|condition:$condition|rule:$rule[|cycle:$cycle|max:$max][;......]
	$rules = $info['rule'];
	$rules = str_replace('{$self}', $self, $rules);
	$rules = explode(';', $rules);
	$return = array();
	foreach ($rules as $key=>&$rule){
		$rule = explode('|', $rule);
		foreach ($rule as $k=>$fields){
			$field = empty($fields) ? array() : explode(':', $fields);
			if(!empty($field)){
				$return[$key][$field[0]] = $field[1];
			}
		}
		//cycle(检查周期)和max(周期内最大执行次数)必须同时存在，否则去掉这两个条件
		if(!array_key_exists('cycle', $return[$key]) || !array_key_exists('max', $return[$key])){
			unset($return[$key]['cycle'],$return[$key]['max']);
		}
	}

	return $return;
}

/**
 * 执行行为
 * @param array $rules 解析后的规则数组
 * @param int $action_id 行为id
 * @param array $user_id 执行的用户id
 * @return boolean false 失败 ， true 成功
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function execute_action($rules = false, $action_id = null, $user_id = null){
	if(!$rules || empty($action_id) || empty($user_id)){
		return false;
	}

	$return = true;
	foreach ($rules as $rule){

		//检查执行周期
		$map = array('action_id'=>$action_id, 'user_id'=>$user_id);
		$map['create_time'] = array('gt', NOW_TIME - intval($rule['cycle']) * 3600);
		$exec_count = M('ActionLog')->where($map)->count();
		if($exec_count > $rule['max']){
			continue;
		}

		//执行数据库操作
		$Model = M(ucfirst($rule['table']));
		$field = $rule['field'];
		$res = $Model->where($rule['condition'])->setField($field, array('exp', $rule['rule']));

		if(!$res){
			$return = false;
		}
	}
	return $return;
}

/**
 * 检测用户是否登录
 * @return integer 0-未登录，大于0-当前登录用户ID
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function is_login(){
	$user = session('user_auth_merchant');
	if (empty($user)) {
		return 0;
	} else {
		return session('user_auth_merchant_sign') == data_auth_sign($user) ? $user['merchant_id'] : 0;
	}
}

/**
 * 检测当前用户是否为管理员
 * @return boolean true-管理员，false-非管理员
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function is_administrator($uid = null){
	$uid = is_null($uid) ? is_login() : $uid;
	return $uid && (intval($uid) === C('USER_ADMINISTRATOR'));
}

/**
 * 获取配置的分组
 * @param string $group 配置分组
 * @return string
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function get_config_group($group=0){
	$list = C('CONFIG_GROUP_LIST');
	return $group?$list[$group]:'';
}

/**
 * 获取配置的类型
 * @param string $type 配置类型
 * @return string
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function get_config_type($type=0){
	$list = C('CONFIG_TYPE_LIST');
	return $list[$type];
}

/**
 * @todo 获取系统环境信息
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function getOsInfo(){
	if(S('os_info')){
		return  S('os_info');
	}else{
		$system_info_mysql = M()->query("select version() as v;");
		$os_config = array(
				'tke_admin_version'		=>	C('TKE_VERSION'),
				'php_os'				=>	PHP_OS,
				'think_version'			=>	THINK_VERSION,
				'soft_ware'				=>	$_SERVER['SERVER_SOFTWARE'],
				'mysql_version'			=>	$system_info_mysql['0']['v'],
				'upload_max_filesize'		=>ini_get('upload_max_filesize'),
		);
		S('os_info',$os_config);
		return $os_config;
	}
}

/**
 * 根据用户ID获取用户登录帐号
 * @param  integer $uid 用户ID
 * @return string       用户昵称
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function get_login_name($uid = 0){
	static $list;
	if(!($uid && is_numeric($uid))){ //获取当前登录用户名
		return session('user_auth.username');
	}

	/* 获取缓存数据 */
	if(empty($list)){
		$list = S('sys_user_nickname_list');
	}

	/* 查找用户信息 */
	$key = "u{$uid}";
	if(isset($list[$key])){ //已缓存，直接使用
		$name = $list[$key];
	} else { //调用接口获取用户信息
		$info = M('Member')->field('login_name')->find($uid);
		if($info !== false && $info['login_name'] ){
			$login_name = $info['login_name'];
			$name = $list[$key] = $login_name;
			/* 缓存用户 */
			$count = count($list);
			$max   = C('USER_MAX_CACHE');
			while ($count-- > $max) {
				array_shift($list);
			}
			S('sys_user_nickname_list', $list);
		} else {
			$name = '';
		}
	}
	return $name;
}

// 分析枚举类型配置值 格式 a:名称1,b:名称2
function parse_config_attr($string) {
	$array = preg_split('/[,;\r\n]+/', trim($string, ",;\r\n"));
	if(strpos($string,':')){
		$value  =   array();
		foreach ($array as $val) {
			list($k, $v) = explode(':', $val);
			$value[$k]   = $v;
		}
	}else{
		$value  =   $array;
	}
	return $value;
}



// 获取数据的状态操作
function show_status_op($status) {
	switch ($status){
		case 0  : return    '启用';     break;
		case 1  : return    '禁用';     break;
		case 2  : return    '审核';		break;
		default : return    false;      break;
	}
}

// 获取数据的类型
function show_type($status) {
    switch ($status){
        case 0  : return    '网页版';     break;
        case 1  : return    '手机版';     break;
        default : return    false;      break;
    }
}

/**
 * 检查$pos(推荐位的值)是否包含指定推荐位$contain
 * @param number $pos 推荐位的值
 * @param number $contain 指定推荐位
 * @return boolean true 包含 ， false 不包含
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function check_document_position($pos = 0, $contain = 0){
	if(empty($pos) || empty($contain)){
		return false;
	}

	//将两个参数进行按位与运算，不为0则表示$contain属于$pos
	$res = $pos & $contain;
	if($res !== 0){
		return true;
	}else{
		return false;
	}
}


/**
 * 获取当前文档的分类
 * @param int $id
 * @return array 文档类型数组
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function get_cate($cate_id = null){
	if(empty($cate_id)){
		return false;
	}
	$cate   =   M('Category')->where('id='.$cate_id)->getField('title');
	return $cate;
}

// 分析枚举类型字段值 格式 a:名称1,b:名称2
// 暂时和 parse_config_attr功能相同
// 但请不要互相使用，后期会调整
function parse_field_attr($string) {
	if(0 === strpos($string,':')){
		// 采用函数定义
		return   eval(substr($string,1).';');
	}elseif(0 === strpos($string,'[')){
		// 支持读取配置参数（必须是数组类型）
		return C(substr($string,1,-1));
	}

	$array = preg_split('/[,;\r\n]+/', trim($string, ",;\r\n"));
	if(strpos($string,':')){
		$value  =   array();
		foreach ($array as $val) {
			list($k, $v) = explode(':', $val);
			$value[$k]   = $v;
		}
	}else{
		$value  =   $array;
	}
	return $value;
}

/**
 * 获取行为数据
 * @param string $id 行为id
 * @param string $field 需要获取的字段
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function get_action($id = null, $field = null){
	static $list;
	if(empty($id) || !is_numeric($id)){
		return '';
	}
	$list = S('action_list');
	if((empty($list[$id]) && is_null($field))||(empty($list[$id][$field]))){
		$info = M('Action')->field($field)->where(array('id'=>$id,'status'=>1))->find();
		if(!$info){
			return '';
		}
		$list[$id] = $info;
		S('action_list', $list,3600); //更新缓存
	}
	return is_null($field) ? $list[$id] : $list[$id][$field];
}

/**
 * @todo 获取行为名称
 */
 function getActionTitle($id){
 	return get_action($id,'title');
 }


/**
 * 获取行为类型
 * @param intger $type 类型
 * @param bool $all 是否返回全部类型
 * @author PHP@妖孽  <dino_ma@163.com>
 */
function get_action_type($type, $all = false){
	$list = array(
			1=>'系统',
			2=>'用户',
	);
	if($all && is_null($type)){
		return $list;
	}
	return $list[$type];
}

/**
 * @todo curl
 * @param string $url
 * @param array $array
 * @return array
 */
function toCurl($url,$array = array()){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $array);
    $data = curl_exec($ch);
    curl_close($ch);
    return json_decode($data, true);
}

